//---------------------------------------------------------------------------
/**
 * \class CSmartTemplate
 * \brief This is a smart reference template class to deal with any type of classes.
 * \version 0.1
 *
 * \author Woo-Hyun Kim (woorung@nhncorp.com, woorung@gmail.com)
 * \author http://blog.naver.com/wisereign .
 *
 * \date 2007/09/04
 *
 * \description Some classes have been referred from
 * \description - http://pages.cpsc.ucalgary.ca/~kremer/STL/1024x768/ref2.html
 * \description - http://www.ddj.com/java/184405409.
 */
//---------------------------------------------------------------------------
#ifndef CSmartTemplateH
#define CSmartTemplateH
//-----------------------------------------------------------------
#include <iostream>
//-----------------------------------------------------------------
using namespace std;
//----------------------------------------------------------------
template <typename T>
class CSmartTemplate {
private:
	bool kill;

protected:
	T *t;

public:
	// copy constructors
	CSmartTemplate(const T &rhs) {
		kill = true;
		t = rhs.clone();
		t->setTTL(rhs.getTTL());
	};
	CSmartTemplate(T *rhs) {
		kill = false;
		t = rhs;
	};
	CSmartTemplate(const CSmartTemplate<T> &rhs) {
		kill = true;	
		t = rhs.t?rhs.t->clone():NULL;
		if(t!=NULL) t->setTTL(rhs.t->getTTL());
	};
	~CSmartTemplate() {
		if(t&&kill) delete t;
	};

	// assign constructor
	CSmartTemplate &operator=(const CSmartTemplate<T> &rhs) {
		if(t&&kill) delete t;
		kill = true;
		t = rhs.t?rhs.t->clone():NULL;
		if(t!=NULL) t->setTTL(rhs.t->getTTL());

		return *this;
	};

	// comparison
	bool operator==(const CSmartTemplate<T> &rhs) const {
/* later =============================================================
cout << "[CSmartTemplate] operator==" << endl;
		bool isEqual = false;
		if(rhs.t==NULL) return isEqual;

		const type_info *lhsTI = t->getTypeEquiv();
		const type_info *rhsTI = rhs.t->getTypeEquiv();

		if(*lhsTI==*rhsTI) {
			isEqual = (t->blindlyEquals(rhs.t));
		}

		return isEqual;
 later ============================================================= */
	};
	bool operator==(const T &rhs) const {
/* later =============================================================
cout << "[CSmartTemplate] operator==" << endl;
		bool isEqual = false;
		if(&rhs==NULL) return isEqual;

		const type_info *lhsTI = t->getTypeEquiv();
		const type_info *rhsTI = rhs.getTypeEquiv();

		if(*lhsTI==*rhsTI) {
			isEqual = (t->blindlyEquals(&rhs));
		}

		return isEqual;
 later ============================================================= */
	};
	int operator<(const CSmartTemplate<T> &rhs) const {
		return t?rhs.t?(*t) < (*rhs.t):false:true;
	};

	// reference thru. pointer 
	T *operator->() const { return t; }; // CSmartTemplate<T>-> == t->
	// dereference thru. pointer
	T &operator*() const { return *t; }; // *CSmartTemplate<T> == *t

	// create pointer variable
	operator T*() const { return t; }; // T *t =  ??
	operator T&() const { return *t; }; // T &t =  ??
};
//----------------------------------------------------------------
#endif
